/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package conlastfm;
import CollaborativeFilttering.Estruturas.MusicSet;
import CollaborativeFilttering.FiltragemColaborativa;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import mdsj.ClassicalScaling;
import mdsj.MDSJ;
/**
 *
 * @author Pedro
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
       /* final int NUM_SONGS = 50;
        Caller.getInstance().setUserAgent("tst");
        Caller.getInstance().setDebugMode(true);

        HashMap<String,Collection<User>> mapa = new HashMap<String, Collection<User>>();
        List<String> verificados = new ArrayList<String>();
        Queue fila = new Queue();
        User user = User.getInfo("pedrohrs08", Autenticacao.APIkey);
        Grafo r = new Grafo();
        User aux = null;



      FiltragemColaborativa filtragem = new FiltragemColaborativa();
      
      List<User> vizinhos = (List<User>)User.getFriends("mario_enzzo", Autenticacao.APIkey);
      int j = 0;
      for(j = 0; j < vizinhos.size(); j++)
      {
          try{
            List<Track> tracks = (List<Track>)User.getRecentTracks(vizinhos.get(j).getName(),50, Autenticacao.APIkey,1).getPageResults();

            List<MusicSet> list = new ArrayList<MusicSet>();
            int i = 0;
            for(Track track : tracks)
            {
               if (i < NUM_SONGS && i < tracks.size())
               {
                 MusicSet m = new MusicSet(track.getName(), track.getArtist());
                 list.add(m);
                 i++;
               }
            }
           filtragem.Filtrar(list);
          }catch(Exception e)
          {
          }
        }
      
        ArrayList<MusicSet> arr = new ArrayList<MusicSet>();
        arr.add(new MusicSet("Musica1","Autor1"));
        arr.add(new MusicSet("Musica2","Autor2"));
        Tupla tupla = new Tupla(arr.get(0),arr.get(1));
        Tupla tupla2 = new Tupla(arr.get(1),arr.get(0));
        System.out.println(tupla.hashCode());
        System.out.println(tupla2.hashCode());
        

        filtragem.Filtrar(arr);
        filtragem.printGrafo();
        arr.clear();
        
        arr.add(new MusicSet("Musica2","Autor2"));
        arr.add(new MusicSet("Musica1","Autor1"));

        tupla = new Tupla(arr.get(0),arr.get(1));
        tupla2 = new Tupla(arr.get(1),arr.get(0));

        System.out.println(tupla.hashCode());
        System.out.println(tupla2.hashCode());
        filtragem.Filtrar(arr);

        arr.clear();
        arr.add(new MusicSet("Good Life","OneRepublic"));
        arr.add(new MusicSet("Dreaming Out Loud","OneRepublic"));
        arr.add(new MusicSet("Good Life","OneRepublic"));
        arr.add(new MusicSet("Dreaming Out Loud","OneRepublic"));
        arr.add(new MusicSet("Broken","Lifehouse"));
        filtragem.Filtrar(arr);
        filtragem.aplicarCoeficienteDoCosseno();
        filtragem.printGrafo();      
        System.out.println(j);
        filtragem.SaveToFile("C:\\Users\\Lilli\\Documents\\MusicSets.txt");
*/
        FiltragemColaborativa filtragem2 = new FiltragemColaborativa();
        filtragem2.LoadFromFile("C:\\Users\\Lilli\\Documents\\MusicSets.txt");
        filtragem2.aplicarCoeficienteDoCosseno();
    //    filtragem2.printGrafo();
        
        filtragem2.ordenaMusicas();
        filtragem2.printMusicasNaRede();
        
        
        int requested = filtragem2.musicasNaRede.indexOf(new MusicSet("Bad Romance", "Lady Gaga"));
        System.out.println(filtragem2.musicasNaRede.contains(new MusicSet("Bad Romance", "Lady Gaga")));
        double[][] matriz = filtragem2.retornaMatrizAdjacencia();
      
        int DIM = 5;
        System.out.println("Tam. Matriz :" + matriz.length);
        double[][] resultado = MDSJ.classicalScaling(matriz,DIM);
        
        double raio = ClassicalScaling.smallestEigenvalue(matriz);
        double[] cordenadas = getCoordinates(requested, DIM, resultado);
   

        TreeMap<Double,MusicSet> mapa2 = new TreeMap<Double, MusicSet>();


        int count = 0;
        for(int o = 0; o < resultado[0].length;o++)
        {
            //System.out.println(sumCordinates(getCoordinates(o, 3, resultado), cordenadas));
           if(sumCordinates(getCoordinates(o, DIM, resultado), cordenadas) < Math.pow(8000,2))
           {
               mapa2.put(sumCordinates(getCoordinates(o, DIM, resultado), cordenadas),filtragem2.musicasNaRede.get(o));
             //  System.out.println(filtragem2.musicasNaRede.get(o).getMusica() + '-' + filtragem2.musicasNaRede.get(o).getAutor());
               count ++;
           }
        }
        System.out.println(count);

        
        File f = new File("C:\\Users\\Lilli\\Documents\\Grafo.txt");
        FileWriter wirter = null;
        try {
            wirter = new FileWriter(f);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        BufferedWriter out = new BufferedWriter(wirter);

        for(int i=0; i<matriz.length; i++) {  // output all coordinates
             String saida = "";
            for(int k = 0; k < resultado.length; k++)
                 {
		    saida += resultado[k][i] +"\t";

                }
                   System.out.println(saida);
            try {
                out.append(saida);
                   out.newLine();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }

		}
        try {
            out.flush();
            /*fila.enqueue(user);
            int i = 0;
            do
            {
            try {
            user = (User) fila.dequeue();
            } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            mapa.put(user.getName(), User.getFriends(user.getName(), Autenticacao.APIkey));
            for(User us: mapa.get(user.getName()))
            {
            r.addEntry(user.getName(), us.getName());
            fila.enqueue(us);
            }
            i++;
            System.out.println(i);
            }while(i < 100);
            /* for(String s: mapa.keySet())
            {
            Iterator it = mapa.get(s).iterator();
            while(it.hasNext())
            {
            User u = (User)it.next();
            for(Collection c: mapa.values())
            {
            Iterator it2 = c.iterator();
            while(it.hasNext())
            {
            User ur = (User)
            for(User u: c.)
            }
            }
            }
            }
            r.printRede();
            Scanner s = new Scanner(System.in);
            String op = "";
            do{
            if(op.equals("a"))
            {
            r.addEntry(s.next(), s.next());
            r.printRede();
            }else if(op.equals("r"))
            {
            r.remEntry(s.next());
            r.printRede();
            }else if(op.equals("v"))
            {
            List<String> lista = new ArrayList<String>();
            r.retornaVizinhos(s.next(),lista);
            for(String str: lista)
            {
            System.out.println(str);
            }
            }
            op = s.next();
            }while(!op.equals("s"));*/
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        for(Double d: mapa2.keySet())
        {

            System.out.print(d + "-");
            System.out.println(mapa2.get(d));
        }
        System.out.println(mapa2.size());
    }

    public static double[] getCoordinates(int index, int dim, double[][]matrix)
    {
        double[] retorno = new double[dim];

        for(int j = 0; j < dim; j++)
        {
            retorno[j] = matrix[j][index];
        }

        return retorno;
    }

    public static double sumCordinates(double[] cordinatesAlpha, double[] cordinatesBeta)
    {
        double retorno = 0;

        for(int i = 0; i < cordinatesAlpha.length; i++)
        {
            retorno += Math.pow(cordinatesAlpha[i] - cordinatesBeta[i], 2);
        }
        return retorno;
    }

}
